/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <vector>
#include <string>
#include <map>

#include <字符串数值互换.h>



template<typename T_NAME, typename T>
struct S_键值序列容器 {

	std::map<T_NAME, T>	gData容器;
	std::map<T, T_NAME>	gData容器_名称;
	std::vector<T>		gData序列容器;


	~S_键值序列容器() {
		gData容器.clear();
		gData容器_名称.clear();
		gData序列容器.clear();
	}



	T& operator [] (const T_NAME& name) {
		return gData容器[name];
	}

	T_NAME operator [] (const T& key) {
		return gData容器_名称[key];
	}

	void f_add(T data, const T_NAME& name) {
		gData容器[name] = data;
		gData容器_名称[data] = name;
		gData序列容器.push_back(data);
	}

	//void f_remove(const T_NAME& name);
	void f_remove(const T_NAME& name) {
		T temp = gData容器[name];

		gData容器_名称.erase(temp);
		gData容器.erase(name);

		uint32 num = gData序列容器.size();
		if (num) {
			T* mat = gData序列容器.data();

			//Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
			for (uint32 i = 0; i < num; ++i) {
				if (mat[i] == temp) {
					gData序列容器[i] = gData序列容器[gData序列容器.size() - 1];
					gData序列容器.pop_back();
					return;
				}
			}
			//});
		}

	}

	std::string f_GenName(const std::string& name) {
		std::string newName = name;
		for (uint32 i = 0; i < 2048; ++i) {
			if (gData容器.find(newName) == gData容器.end()) {
				break;
			}
			newName = name + f_整数值转字符串(i);
		}

		return newName;
	}
	uint32 f_GenName(const uint32 name) {
		uint32 newName = name;
		bool	is成功 = false;
		for (uint32 i = 0; i < 2048; ++i) {
			if (gData容器.find(newName) == gData容器.end()) {
				is成功 = true;
				break;
			}
			newName = name + i;
		}

		if (is成功 == false) {
			std::cout << "错误 S_键值序列容器 添加 uint32 key 键值以存在" << std::endl;
		}

		return newName;
	}


	bool f_Key存在(const T_NAME& name) {
		if (gData容器.find(name) != gData容器.end()) {
			return true;
		}
		return false;
	}
	bool f_is存在(const T& name) {
		if (gData容器_名称.find(name) != gData容器_名称.end()) {
			return true;
		}
		return false;
	}
	bool f_isIndex(const uint32 id) {
		if (id < gData序列容器.size()) {
			return true;
		}
		return false;
	}
	inline uint32 size() {
		return uint32(gData序列容器.size());
	}
	inline T* data() { return gData序列容器.data(); }


	uint32	f_getIndex(const T_NAME& key) {
		T data = (*this)[key];
		uint32 num = gData序列容器.size();
		T* p = gData序列容器.data();
		for (uint32 i = 0; i < num; ++i) {
			if (data == p[i]) {
				return i;
			}
		}

		return 0xffffffff;
	}

	inline T& f_Get(uint32 index) {
		return gData序列容器[index];
	}

	void f_ReKey(const T_NAME& oldKey, const T_NAME& newKey) {
		f_add((*this)[oldKey], newKey);
		f_remove(oldKey);
	}

};

